import pandas as pd
from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori, association_rules

# 定义商品类别映射
category_mapping = {
    '智能手机': '电子产品', '笔记本电脑': '电子产品', '平板电脑': '电子产品',
    '智能手表': '电子产品', '耳机': '电子产品', '音响': '电子产品',
    '相机': '电子产品', '摄像机': '电子产品', '游戏机': '电子产品',
    '上衣': '服装', '裤子': '服装', '裙子': '服装', '内衣': '服装',
    '鞋子': '服装', '帽子': '服装', '手套': '服装', '围巾': '服装',
    '外套': '服装', '零食': '食品', '饮料': '食品', '调味品': '食品',
    '米面': '食品', '水产': '食品', '肉类': '食品', '蛋奶': '食品',
    '水果': '食品', '蔬菜': '食品', '家具': '家居', '床上用品': '家居',
    '厨具': '家居', '卫浴用品': '家居', '文具': '办公', '办公用品': '办公',
    '健身器材': '运动户外', '户外装备': '运动户外', '玩具': '玩具',
    '模型': '玩具', '益智玩具': '玩具', '婴儿用品': '母婴',
    '儿童课外读物': '母婴', '车载电子': '汽车用品', '汽车装饰': '汽车用品'
}


# 1. 加载数据
purchased_history = pd.read_csv('D:/DTR/MyWork/2025/DataMining/personalProject/output/items_10G_one.csv')
product = pd.read_csv('D:/DTR/MyWork/2025/DataMining/personalProject/output/product.csv')

# 2. 数据预处理
# 转换items列为列表类型（处理可能的非字符串格式）
purchased_history['items'] = purchased_history['items'].astype(str).apply(lambda x: eval(x) if x.startswith('[') else [x])

# 筛选退款数据
refund_purchased_history = purchased_history[purchased_history['payment_status'].isin(['已退款', '部分退款'])]
already_refund = purchased_history[purchased_history['payment_status'].isin(['已退款'])]
partial_refund = purchased_history[purchased_history['payment_status'].isin(['部分退款'])]

print('转换后refund_df的基本信息：')
refund_purchased_history.info()
already_refund.info()
partial_refund.info()

# 查看refund_df行数和列数
rows, columns = refund_purchased_history.shape

if rows < 100 and columns < 20:
    # 短表数据（行数少于100且列数少于20）查看全量数据信息
    print('转换后refund_df全部内容信息：')
    print(already_refund.to_csv(sep='\t', na_rep='nan'))
else:
    # 长表数据查看数据前几行信息
    print('转换后refund_df前几行内容信息：')
    print(already_refund.head().to_csv(sep='\t', na_rep='nan'))


# 3. 商品ID映射到类别
def id_to_category(item_list):
    categories = []
    for item_id in item_list:
        # 处理可能的非整数ID（如异常值过滤）
        if isinstance(item_id, int):
            category = product[product['id'] == item_id]['category'].values
            if len(category) > 0:
                categories.append(category[0])

    return categories

# 将商品类别进行映射
already_refund['categories'] = already_refund['items'].apply(id_to_category)
partial_refund['categories'] = partial_refund['items'].apply(id_to_category)
print(f"已退款的数量为{already_refund['categories'].shape}")
print(f"部分退款的数量为{partial_refund['categories'].shape}")


import pandas as pd
from mlxtend.preprocessing import TransactionEncoder
from mlxtend.frequent_patterns import apriori, association_rules


# 1. 将类别列转换为适合Apriori算法的格式（交易列表）
# 查看 categories 列中不同数据类型的分布
type_distribution = already_refund['categories'].apply(type).value_counts()
print("数据类型分布：")
print(type_distribution)

# 查看前几个值及其类型
print("\n前几个值及其类型：")
for idx, value in already_refund['categories'].head().items():
    print(f"索引 {idx}: 类型={type(value)}, 值={value}")
transactions = already_refund['categories'].apply(lambda x: x if isinstance(x, list) else [])


# 2. 使用TransactionEncoder转换数据
te = TransactionEncoder()
te_ary = te.fit(transactions).transform(transactions)
df_encoded = pd.DataFrame(te_ary, columns=te.columns_)

# 3. 使用Apriori算法挖掘频繁项集
frequent_itemsets = apriori(df_encoded, min_support=0.001, use_colnames=True)

# 4. 生成关联规则
rules = association_rules(frequent_itemsets, metric="confidence", min_threshold=0.5)

# 5. 筛选并展示结果
refund_rules = rules.sort_values('lift', ascending=False)
print("与退款状态强相关的商品类别组合：")
print(refund_rules[['antecedents', 'consequents', 'support', 'confidence', 'lift']])

